package com.hksj.Intelligentmanagement.service;

import com.hksj.Intelligentmanagement.common.Result;
import com.hksj.Intelligentmanagement.dto.GasAlarmTrendDTO;
import com.hksj.Intelligentmanagement.dto.GasMonitoringDTO;
import com.hksj.Intelligentmanagement.dto.GasTrendDTO;
import com.hksj.Intelligentmanagement.mapper.AlarmRecordMapper;
import com.hksj.Intelligentmanagement.mapper.GasHistoryMapper;
import com.hksj.Intelligentmanagement.mapper.GasInfoMapper;
import com.hksj.Intelligentmanagement.utils.ExportExcelUtil;
import com.hksj.Intelligentmanagement.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @ClassName GasMonitoringService
 * @Author zengke
 * @Date 2023/7/18 14:16
 */

@Service
public class GasMonitoringService {

    @Autowired
    private GasInfoMapper gasInfoMapper;

    @Autowired
    private GasHistoryMapper gasHistoryMapper;

    @Autowired
    private AlarmRecordMapper alarmRecordMapper;

    //查询医气总览
    public Result queryGasMonitoringInfo(GasMonitoringDTO gasMonitoringDTO){

        //先通过数据库查询出气体压力的列表
        List<GasMonitoringInfoVo> gasPressureInfoVos = gasInfoMapper.queryGasPressureInfo(gasMonitoringDTO);

        List<GasMonitoringInfoVo> gasPressureHistoryVos = gasInfoMapper.queryGasPressureHistory(gasMonitoringDTO);

        //遍历gasPressureInfoVos列表
        gasPressureInfoVos.forEach(gasPressureInfoVo -> {
            String alarmThreshold = gasPressureInfoVo.getAlarmThreshold();

            String[] alarmThresholdArray = alarmThreshold.split(",");

            //若alarmThresholdArray长度为1则表示是流量,只有最大阈值
            if (alarmThresholdArray.length == 1){
                gasPressureInfoVo.setHighPressure(alarmThreshold);

                //若当前值大于最大阈值 不能使用String.compareTo方法来比较 因为 若 a=9,b=10.8 a.compareTo(b)它大于0表示a>b不符合预期
                //可以先将String转为Double再进行比较
                if (Double.parseDouble(gasPressureInfoVo.getRealTimePressure()) > Double.parseDouble(alarmThreshold)){
                    gasPressureInfoVo.setPressureSituation("1");
                } else {
                    gasPressureInfoVo.setPressureSituation("0");
                }
            } else {
                //否则只有两个值一个最大值一个最小值
                String min = alarmThresholdArray[0];
                String max = alarmThresholdArray[1];
                gasPressureInfoVo.setLowPressure(min);
                gasPressureInfoVo.setHighPressure(max);

                //若实时值小于最小阈值
                if (Double.parseDouble(gasPressureInfoVo.getRealTimePressure()) < Double.parseDouble(min)){
                    gasPressureInfoVo.setPressureSituation("-1");
                } else if(Double.parseDouble(gasPressureInfoVo.getRealTimePressure()) > Double.parseDouble(max)){
                    gasPressureInfoVo.setPressureSituation("1");
                } else{
                    gasPressureInfoVo.setPressureSituation("0");
                }

            }

            //遍历gasPressureHistoryVos列表 若gasMonitoringInfoVo中的gasId、departmentId、buildingId和gasPressureHistoryVo中的相同则将gasPressureHistoryVo里的x、y轴数据设置到gasMonitoringInfoVo中
            gasPressureHistoryVos.forEach(gasPressureHistoryVo ->{
                if (gasPressureInfoVo.getGasId().equals(gasPressureHistoryVo.getGasId()) &&
                        gasPressureInfoVo.getBuildingId().equals(gasPressureHistoryVo.getBuildingId()) &&
                        gasPressureInfoVo.getDepartmentId().equals(gasPressureHistoryVo.getDepartmentId())){

                    //设置峰谷平值
                    gasPressureInfoVo.setPressurePeek(gasPressureHistoryVo.getPressurePeek());
                    gasPressureInfoVo.setPressureValley(gasPressureHistoryVo.getPressureValley());
                    gasPressureInfoVo.setAveragePressure(gasPressureHistoryVo.getAveragePressure());

                    //设置x轴、y轴数据
                    gasPressureInfoVo.setXData(gasPressureHistoryVo.getX().split(","));
                    gasPressureInfoVo.setYData(gasPressureHistoryVo.getY().split(","));
                }
            });

            //设置时间类型
            gasPressureInfoVo.setTimeType(gasMonitoringDTO.getTimeType());
        });

        //返回查询数据
        return Result.data(gasPressureInfoVos);
    }

    //查询气体压力趋势
    public List<GasTrendVo> queryGasPressureTrend(GasTrendDTO gasTrendDTO){

        //通过gasHistory的queryGasPressureTrend方法查询气体压力趋势
        List<GasTrendVo> gasPressureTrendVos = gasHistoryMapper.queryGasPressureTrend(gasTrendDTO);

        //遍历查询的到的列表数据
        gasPressureTrendVos.forEach(gasPressureTrendVo -> {
            //将vo中x轴数据转为数组数据
            gasPressureTrendVo.setXData(gasPressureTrendVo.getX().split(","));
            //将vo中x轴数据转为数组数据
            gasPressureTrendVo.setYData(gasPressureTrendVo.getY().split(","));
        });

        //返回处理完的数据
        return gasPressureTrendVos;

    }

    //查询气体用量趋势 传气体id、科室id、楼栋id、开始时间结束时间
    public Result queryGasUsageTrend(GasTrendDTO gasTrendDTO){

        //通过gasHistoryMapper的queryOxygenUsageTrend方法
        List<GasTrendVo> gasOxygenUsageTrendVos = gasHistoryMapper.queryGasUsageTrend(gasTrendDTO);

        //遍历查询到的数据
        gasOxygenUsageTrendVos.forEach(gasOxygenUsageTrendVo -> {
            //将vo中x轴数据转为数组数据
            gasOxygenUsageTrendVo.setXData(gasOxygenUsageTrendVo.getX().split(","));
            //将vo中x轴数据转为数组数据
            gasOxygenUsageTrendVo.setYData(gasOxygenUsageTrendVo.getY().split(","));
        });

        //将处理完的数据返回
        return Result.data(gasOxygenUsageTrendVos);

    }

    //查询气体告警压力趋势 前端传的时间为 "1970-01-01"
    public Result queryGasAlarmPressureTrend(GasAlarmTrendDTO gasAlarmTrendDTO){

        //通过气体id、楼栋id、科室id查询出该气体的最大阈值和最小阈值
        GasAlarmTrendVo gasAlarmTrendVo = alarmRecordMapper.queryGasAlarmThreshold(gasAlarmTrendDTO);

        //判断threshold转成的数组长度是否为1
        String alarmThreshold = gasAlarmTrendVo.getAlarmThreshold();

        String[] alarmThresholdArr = alarmThreshold.split(",");

        if (alarmThresholdArr.length ==1){
            //等于1 只有最大阈值
            gasAlarmTrendVo.setHighPressure(alarmThreshold);
        } else {
            //有最大阈值和最小阈值
            //且此处的最大阈值和最小阈值有可能是负压的阈值,最大阈值和最小阈值会反向
            String min = alarmThresholdArr[0];
            String max = alarmThresholdArr[1];
            if (Double.parseDouble(min) > Double.parseDouble(max) ){
                //为负压气体时
                gasAlarmTrendVo.setLowPressure(max);
                gasAlarmTrendVo.setHighPressure(min);
            }else {
                //为其他气体时
                gasAlarmTrendVo.setLowPressure(min);
                gasAlarmTrendVo.setHighPressure(max);
            }
        }

        //查询告警压力趋势
        GasAlarmTrendVo gasAlarmPressureTrendVo = alarmRecordMapper.queryGasAlarmPressureTrend(gasAlarmTrendDTO);

        if (Objects.isNull(gasAlarmPressureTrendVo)){
            //查询的压力趋势为空则表明在该时间段内该气体没有告警信息,直接返回结果
            return Result.data(gasAlarmTrendVo);
        }
        //将气体告警趋势的x轴数据转换成数组形式
        String[] xData = gasAlarmPressureTrendVo.getX().split(",");

        //将气体告警趋势的y轴数据转换成数组形式
        String[] yData = gasAlarmPressureTrendVo.getY().split(",");

        //将气体告警趋势的x轴数据和y轴数据设置到gasAlarmTrendVo中
        gasAlarmTrendVo.setXData(xData);
        gasAlarmTrendVo.setYData(yData);

        return Result.data(gasAlarmTrendVo);

    }

    //查询气体用量告警
    public Result queryGasUsageAlarmTrend(GasAlarmTrendDTO gasAlarmTrendDTO){

        //通过气体id、楼栋id、科室id查询出该气体的最大阈值和最小阈值
        GasAlarmTrendVo gasAlarmTrendVo = alarmRecordMapper.queryGasAlarmThreshold(gasAlarmTrendDTO);

        //判断threshold转成的数组长度是否为1
        String alarmThreshold = gasAlarmTrendVo.getAlarmThreshold();

        String[] alarmThresholdArr = alarmThreshold.split(",");

        if (alarmThresholdArr.length ==1){
            //等于1 只有最大阈值
            gasAlarmTrendVo.setHighPressure(alarmThreshold);
        } else {
            //有最大阈值和最小阈值
            //且此处的最大阈值和最小阈值有可能是负压的阈值,最大阈值和最小阈值会反向
            String min = alarmThresholdArr[0];
            String max = alarmThresholdArr[1];
            if (Double.parseDouble(min) > Double.parseDouble(max) ){
                //为负压气体时
                gasAlarmTrendVo.setLowPressure(max);
                gasAlarmTrendVo.setHighPressure(min);
            }else {
                //为其他气体时
                gasAlarmTrendVo.setLowPressure(min);
                gasAlarmTrendVo.setHighPressure(max);
            }
        }

        //查询气体用量告警
        GasAlarmTrendVo gasGasUsageAlarmTrendVo = alarmRecordMapper.queryGasUsageAlarmTrend(gasAlarmTrendDTO);

        if (Objects.isNull(gasGasUsageAlarmTrendVo)){
            //查询的压力趋势为空则表明在该时间段内该气体没有告警信息,直接返回结果
            return Result.data(gasAlarmTrendVo);
        }
        //将气体告警趋势的x轴数据转换成数组形式
        String[] xData = gasGasUsageAlarmTrendVo.getX().split(",");

        //将气体告警趋势的y轴数据转换成数组形式
        String[] yData = gasGasUsageAlarmTrendVo.getY().split(",");

        //将气体告警趋势的x轴数据和y轴数据设置到gasAlarmTrendVo中
        gasAlarmTrendVo.setXData(xData);
        gasAlarmTrendVo.setYData(yData);

        return Result.data(gasAlarmTrendVo);

    }

    //导出气体压力趋势的excel
    public void exportGasPressureTrend(GasTrendDTO gasTrendDTO, HttpServletResponse response){
        //先查询气体压力趋势
        List<ExportGasTrendVo> gasTrendVos = gasHistoryMapper.queryGasPressureTrendData(gasTrendDTO);

        //判断数据源是否为空
        if (CollectionUtils.isEmpty(gasTrendVos)){
            return;
        }
        List<ExportGasTrendVo> gasTrendData =new ArrayList<>();
        for (ExportGasTrendVo gasTrendVo : gasTrendVos) {
            //将压力值字符串转为数组
            String[] pressureValueArr = gasTrendVo.getPressureValue().split(",");

            //将监测时间字符串转为数组
            String[] monitorTimeArr = gasTrendVo.getMonitorTime().split(",");

            for (int i = 0 ; i< pressureValueArr.length;i++){

                ExportGasTrendVo exportGasPressureTrendVo = new ExportGasTrendVo();

                exportGasPressureTrendVo.setGasName(gasTrendVo.getGasName());
                exportGasPressureTrendVo.setArea(gasTrendVo.getArea());
                exportGasPressureTrendVo.setPressureRange(gasTrendVo.getPressureRange().replace(",","-"));
                exportGasPressureTrendVo.setPressureValue(pressureValueArr[i]);
                exportGasPressureTrendVo.setMonitorTime(monitorTimeArr[i]);

                gasTrendData.add(exportGasPressureTrendVo);
            }

        }

        //导出
        //跳过行数
        int skipRow = 2;

        //模板路径
        String path = "classpath:gas_template/gas_pressure_trend_excel_module.xlsx";

        //文件名称
        String fileName = "医用气体压力趋势.xlsx";
        //调用导出excel的方法
        ExportExcelUtil.export(path,skipRow,fileName,gasTrendData,null,response,null);

    }

    //导出气体用量的excel
    public void exportGasUsageTrend(GasTrendDTO gasTrendDTO, HttpServletResponse response){

        //先查询气体用量趋势
        List<ExportGasTrendVo> gasTrendVos = gasHistoryMapper.queryGasUsageTrendData(gasTrendDTO);

        //判断数据源是否为空
        if (CollectionUtils.isEmpty(gasTrendVos)){
            return;
        }
        List<ExportGasTrendVo> gasTrendData =new ArrayList<>();
        for (ExportGasTrendVo gasTrendVo : gasTrendVos) {
            //将压力值字符串转为数组
            String[] pressureValueArr = gasTrendVo.getPressureValue().split(",");

            //将监测时间字符串转为数组
            String[] monitorTimeArr = gasTrendVo.getMonitorTime().split(",");

            for (int i = 0 ; i< pressureValueArr.length;i++){

                ExportGasTrendVo exportGasPressureTrendVo = new ExportGasTrendVo();

                exportGasPressureTrendVo.setGasName(gasTrendVo.getGasName());
                exportGasPressureTrendVo.setArea(gasTrendVo.getArea());
                exportGasPressureTrendVo.setPressureRange(gasTrendVo.getPressureRange().replace(",","-"));
                exportGasPressureTrendVo.setPressureValue(pressureValueArr[i]);
                exportGasPressureTrendVo.setMonitorTime(monitorTimeArr[i]);

                gasTrendData.add(exportGasPressureTrendVo);
            }

        }

        //导出
        //跳过行数
        int skipRow = 2;

        //模板路径
        String path = "classpath:gas_template/gas_usage_trend_excel_module.xlsx";

        //文件名称
        String fileName = "氧气用量趋势.xlsx";
        //调用导出excel的方法
        ExportExcelUtil.export(path,skipRow,fileName,gasTrendData,null,response,null);
    }

    //导出告警的excel的data (同时满足告警压力和告警用量的查询)
    private List<ExportGasAlarmTrendVo> queryGasAlarmPressureAndUsageTrend(GasTrendDTO gasTrendDTO){

        //创建一个浮点数转换对象 给一个匹配规则
        DecimalFormat df = new DecimalFormat("######0.00");

        //先查询气体压力告警趋势
        List<ExportGasAlarmTrendVo> gasTrendVos = alarmRecordMapper.queryGasAlarmPressureTrendData(gasTrendDTO);

        //判断数据源是否为空
        if (CollectionUtils.isEmpty(gasTrendVos)){
            return null;
        }

        List<ExportGasAlarmTrendVo> gasTrendData =new ArrayList<>();
        for (ExportGasAlarmTrendVo gasTrendVo : gasTrendVos) {
            //将压力值字符串转为数组
            String[] alarmValueArr = gasTrendVo.getAlarmValue().split(",");

            //将监测时间字符串转为数组
            String[] alarmTimeArr = gasTrendVo.getAlarmTime().split(",");

            for (int i = 0 ; i< alarmValueArr.length;i++){

                ExportGasAlarmTrendVo exportGasAlarmTrendVo= new ExportGasAlarmTrendVo();

                exportGasAlarmTrendVo.setGasName(gasTrendVo.getGasName());
                exportGasAlarmTrendVo.setArea(gasTrendVo.getArea());
                exportGasAlarmTrendVo.setPressureRange(gasTrendVo.getPressureRange().replace(",","-"));

                exportGasAlarmTrendVo.setAlarmTime(alarmTimeArr[i]);
                String[] pressureRangeArr = gasTrendVo.getPressureRange().split(",");

                //若pressureRangeArr长度为1则查询的是流量
                if (pressureRangeArr.length ==1){
                    //大于最大阈值
                    exportGasAlarmTrendVo.setAlarmValue(alarmValueArr[i] + "⬆");

                    //计算偏差值
                    double deviationValue = (Double.parseDouble(alarmValueArr[i]) - Double.parseDouble(pressureRangeArr[0])) / Double.parseDouble(pressureRangeArr[0]);

                    //将偏差值保留两位小数 并设置偏差量
                    exportGasAlarmTrendVo.setDeviationValue(df.format(deviationValue) + "%");
                } else {
                    //判断告警值是偏高还是偏低
                    if (Double.parseDouble(alarmValueArr[i]) < Double.parseDouble(pressureRangeArr[0])){
                        //小于最小阈值
                        exportGasAlarmTrendVo.setAlarmValue(alarmValueArr[i] + "⬇");

                        //计算偏差值
                        double deviationValue = (Double.parseDouble(pressureRangeArr[0]) - Double.parseDouble(alarmValueArr[i])) / Double.parseDouble(pressureRangeArr[0]);

                        //将偏差值保留两位小数 并设置偏差量
                        exportGasAlarmTrendVo.setDeviationValue(df.format(deviationValue) + "%");

                    } else if(Double.parseDouble(alarmValueArr[i]) >= Double.parseDouble(pressureRangeArr[1])){
                        //大于最大阈值
                        exportGasAlarmTrendVo.setAlarmValue(alarmValueArr[i] + "⬆");

                        //计算偏差量
                        double deviationValue = (Double.parseDouble(alarmValueArr[i]) - Double.parseDouble(pressureRangeArr[1])) / Double.parseDouble(pressureRangeArr[1]);

                        //计算偏差量 并设置偏差量
                        exportGasAlarmTrendVo.setDeviationValue(df.format(deviationValue) + "%");
                    }
                }
                gasTrendData.add(exportGasAlarmTrendVo);
            }
        }
        return gasTrendData;
    }

    //导出医用气体告警趋势
    public void exportGasPressureAlarmTrend(GasTrendDTO gasTrendDTO, HttpServletResponse response){
        //获取气体告警趋势数据集合
        List<ExportGasAlarmTrendVo> exportGasAlarmTrendVos = queryGasAlarmPressureAndUsageTrend(gasTrendDTO);

        //判断该集合是否为空,为空则直接
        if (CollectionUtils.isEmpty(exportGasAlarmTrendVos)){
            return;
        }

        //导出
        //跳过行数
        int skipRow = 2;

        //模板路径
        String path = "classpath:gas_template/gas_pressure_alarm_trend_excel_module.xlsx";

        //文件名称
        String fileName = "医用气体压力告警趋势.xlsx";
        //调用导出excel的方法
        ExportExcelUtil.export(path,skipRow,fileName,exportGasAlarmTrendVos,null,response,null);

    }

    //导出气体用量告警趋势
    public void exportGasUsageAlarmTrend(GasTrendDTO gasTrendDTO, HttpServletResponse response){
        //获取气体用量告警趋势数据集合
        List<ExportGasAlarmTrendVo> exportGasAlarmTrendVos = queryGasAlarmPressureAndUsageTrend(gasTrendDTO);

        //判断该集合是否为空,为空则直接
        if (CollectionUtils.isEmpty(exportGasAlarmTrendVos)){
            return;
        }

        //导出
        //跳过行数
        int skipRow = 2;

        //模板路径
        String path = "classpath:gas_template/gas_usage_alarm_trend_excel_module.xlsx";

        //文件名称
        String fileName = "气体用量告警趋势.xlsx";

        //调用导出excel的方法
        ExportExcelUtil.export(path,skipRow,fileName,exportGasAlarmTrendVos,null,response,null);
    }

}
